package CSV;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;

public class RuleFinder {

	double minconf;
	HashMap<ArrayList<String>, Integer> LHSRHS;

	public RuleFinder(HashMap<ArrayList<String>, Integer> LHSRHS, double minsconf){
		this.minconf = minsconf;
		this.LHSRHS = new HashMap<ArrayList<String>, Integer>();
		this.LHSRHS = LHSRHS;
	}

	public HashMap<Rules, Double> findRules(){
		// confidence part
		// for each element in the Answer set
		HashMap<Rules, Double> answer = new HashMap<Rules, Double>();
		Iterator<ArrayList<String>> LRiter = this.LHSRHS.keySet().iterator();
		while (LRiter.hasNext()){
			ArrayList<String> element = LRiter.next();
			ArrayList<ArrayList<String>> subsetList = new ArrayList<ArrayList<String>>();
			subsetList = findSubSet(element);
			int length = subsetList.size();
			for (int i = 0; i < length; i++){
				ArrayList<String> pLHS = new ArrayList<String>();
				pLHS = subsetList.get(i);
				
				// System.out.println(LHSRHS.get(element));
				// System.out.println(LHSRHS.get(pLHS));
				// System.out.println("\n");
				double nominator = LHSRHS.get(element);
				double denominator = LHSRHS.get(pLHS);
				double conf = nominator / denominator;
				if (conf > minconf){
					// System.out.println(conf);
					ArrayList<String> RHS = new ArrayList<String>();
					Iterator<String> eiter = element.iterator();
					while(eiter.hasNext()){
						String item = (String)eiter.next();
						if (!pLHS.contains(item)){
							RHS.add(item);
						}
					}
					Collections.sort(RHS);
					Rules rule = new Rules(pLHS, RHS);
					answer.put(rule,conf);
				}
			}
		}
		return answer;
	}

	@SuppressWarnings("unchecked")
	private ArrayList<ArrayList<String>> findSubSet(ArrayList<String> hs){

		// find the size of the hash set
		int k = hs.size();
		ArrayList<ArrayList<String>> answer = new ArrayList<ArrayList<String>>();
		String[] items = new String[k];
		Iterator<String> hsiter = hs.iterator();
		int count = 0;
		while (hsiter.hasNext()){
			String item = (String)hsiter.next();
			items[count] = item;
			count ++;
		}

		/*
		// find all the subset by bitmap
		int end = (int) (Math.pow(2, k) - 1);
		for(int i = 1; i < end; i++){
			// fulfill 0 to the beginning
			String str = Integer.toBinaryString(i);
			while (str.length()<k){
				str = "0"+str;
			}

			HashSet<String> ele = new HashSet<String>();
			for (int j = 0; j < k; j++){
				if (str.charAt(j) == '1'){
					ele.add(items[j]);
				}
			}

			answer.add(ele);
		}
		 */
		// find the subset with all elements except 1. so the RHS could only be 1 item
		if ( k != 1)
			for (int i = 0; i < k ; i++){
				ArrayList<String> ele = new ArrayList<String>();
				ele = (ArrayList<String>) hs.clone();
				ele.remove(items[i]);
				answer.add(ele);
			}

		return answer;
	}

}
